Authorization and Integration
This chapter provides a comprehensive guide on how to integrate your application with Corvina, covering both frontend and backend aspects. You'll learn how to handle authentication, manage API calls, and utilize Corvina's tools and libraries to streamline the integration process.
Frontend integration
Your application will be integrated in the Corvina frontend via iframe using the hooks.globalPage.url
property defined in the manifest.json file. The url defined in the hooks.globalPage.url
property will be called with the following query parameters:
accessToken
: the jwt token representing the user that is using your applicationinstanceId
: the id of the Corvina instance where the application is installedorganizationId
: the id of the organization where the application is installedcorvinaHost
: the url encoded baseUrl of the Corvina instance where the application is installedlocale
: the locale of the user that is using your application, in the formatlanguage_country
apiVersion
: the user's is trying to access your application attempting to use this API version (see Application upgrade for more details)
The resulting url will be something like this:
https://nodered.corvina.cloud/#/?apiVersion=1.0.21&locale=it_IT&instanceId=c9beedd2-6c15-4c85-bb2f-50ec579c9ae6&organizationId=36&corvinaHost=https%3A%2F%2Fapp.corvina.io&accessToken=...
It's important to notice that if you specify avoidCorvinaQueryParams
the resulting url will be:
https://node-red.corvina.cloud/#/
Use the javascript function decodeURIComponent
to decode the corvinaHost
parameter.
const corvinaHost = decodeURIComponent('https%3A%2F%2Fapp.corvina.io');
console.log(corvinaHost); // https://app.corvina.io
If the user change the organization, the organizationId
parameter will be updated.
The smartest way to integrate your application with Corvina is using our frontend library called corvina-app-connect. It's written in typescript to give you the best developer experience.
You can use it installing via npm or referencing it in your html page!
This library will help you to:
- retrieve the jwt token representing the user that is using your application, so you can use it to perform frontend calls to Corvina services
- get notified when the jwt token is refreshed
- get notified when the user changes the organization (this is useful if your
hooks.globalPage.url
refers to a Single Page Application) - provide an interface to popup transactions requests
- ...and some more utilities
We develop this library because we want to support server side rendering and client side rendering as well.
Backend authentication
Once you perform the frontend integration, you can use the jwt token to authenticate API calls or websocket connections to your backend. You can call the openIdConfigurationUrl
to retrieve the public key of the jwt token and use it to verify the token (we suggest you to cache result, the rolling of the public key doesn't happen often).
The jwt token content will respect this interface:
interface ICorvinaToken {
// More details here https://www.rfc-editor.org/rfc/rfc7519
// validate it! This string must contain the authBaseUrl from the installation API payload
iss: string,
// validate it! This property must contain the clientId from the installation API payload
aud: string | string[],
sub: string,
// validate it!
exp: number,
iat: number,
jti: string,
typ: string,
email?: string,
email_verified: boolean,
preferred_username: string,
realm_access: {
// validate it! It's the role that you can use to check if the user can access your application, one of the roles must match the `realmValidationRole` from the installation API payload
roles: string[],
},
// validate it! Scope contains key:value tuples, like the destination org and the app identifier.
// You should check that this token refers to your app
scope?: string,
}
If you want to detect the username of the user that is using your application, you can use the preferred_username
field. If the jwt refers to a service account, the preferred_username
field has the following format:
service-account-user-service-<name>@<organization-host-name>
You can remove the service-account-user-service-
prefix to get the name of the service account.
For complex applications with complex role system, the jwt token size can be greater than 4kb. In this case, we suggest you to increase the maxHttpHeaderSize
of your http server.
Backend integration
If the backend of your application needs to communicate with Corvina APIs, you can use the clientId
and clientSecret
from the installation API payload to authenticate your application to Corvina. You can use the apiBaseUrl
from the installation API payload to call the services.
Example of login with clientId and clientSecret:
curl -X POST https://auth.corvina.io/auth/realms/sample1/protocol/openid-connect/token \
-H 'Authorization: Basic dXNlci1zZXJ2aWNlLXRlc3RpbmdAZXhvcjozODUzY2IyNS1kY2E4LTQwMGItYWE5Ni1iNDllYzUyNjExOTg=' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'grant_type=client_credentials&scope=org:myorg.example'
If you are not familiar with basic authentication, you can use
clientId:clientSecret
to generate the base64 encoded string that you need to pass in theAuthorization
header.
The response will be:
{
"upgraded": false,
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI2VDFJNERXOHhtLURuNnNvdDJJclR0cTc4NG4yMDBfUGpOTGRiX1pQY3RRIn0.eyJleHAiOjE3NDQyODI2NjAsImlhdCI6MTc0NDI4MTc2MCwianRpIjoiNmQyOGVhMzAtMzFhNS00OTE0LTk3OGMtMDI3ZDNhZTVhYTYyIiwiaXNzIjoiaHR0cHM6Ly9hdXRoLmNvcnZpbmEubWsvYXV0aC9yZWFsbXMvZXhvciIsImF1ZCI6ImFjY291bnQiLCJzdWIiOiI0NTYzYTA0Yi0xODg3LTQ3M2MtODZlYy01NThiMTYxMTI0ZjYiLCJ0eXAiOiJCZWFyZXIiLCJhenAiOiJ1c2VyLXNlcnZpY2Utc2EtY29ydmluYS1hcHAtY2lzc0BleG9yIiwiYWNyIjoiMSIsInJlYWxtX2FjY2VzcyI6eyJyb2xlcyI6WyJkZWZhdWx0LXJvbGVzLWV4b3IiLCJvZmZsaW5lX2FjY2VzcyIsInVtYV9hdXRob3JpemF0aW9uIl19LCJzY29wZSI6Im9yZzoqIHByb2ZpbGUgZW1haWwiLCJhdXRob3JpemF0aW9uIjp7InBlcm1pc3Npb25zIjpbeyJzY29wZXMiOlsiaWFtLmRldmljZXMucmVhZCIsImlhbS5vcmdhbml6YXRpb25zLnJlYWQiLCJpYW0uZGV2aWNlcy51cGRhdGUiXSwicnNuYW1lIjoiZXhvciJ9XX0sImNsaWVudEhvc3QiOiIxMC4yNDQuMC4xIiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJyZWFsbV9hY2Nlc3MiOnsicm9sZXMiOlsiZXhvci5yb2xlcy5kYXRhX3NhLXJvbGUtY29ydmluYS1hcHAtY2lzcy13aDhhbCIsImV4b3Iucm9sZXMuYXBwX3NhLXJvbGUtY29ydmluYS1hcHAtY2lzcyJdfSwicHJlZmVycmVkX3VzZXJuYW1lIjoic2VydmljZS1hY2NvdW50LXVzZXItc2VydmljZS1zYS1jb3J2aW5hLWFwcC1jaXNzQGV4b3IiLCJjbGllbnRBZGRyZXNzIjoiMTAuMjQ0LjAuMSIsImNsaWVudF9pZCI6InVzZXItc2VydmljZS1zYS1jb3J2aW5hLWFwcC1jaXNzQGV4b3IifQ.TRFzKMWNwy5u5GVGVGtWUPHiyVsWfTO09gNTqm-FLIYSEsesQF-NGyL0kp2i-5A_A07cnkXqkPXQMDgghqKSAC7cC_Zip9UMlNzoq0uAxiwRAMhzpGjcaW89rm4FRkS-uprN7M9zqjB3oW3qOjAwQm3h1H0Kd7qzvzveQv8Zqe0hcxi8YQtmupSYGoC9evKTvssOA2psuvQeVfbWCFYQHnN0X_n9U6U8bRr2F1iUnruVmcgAyeNrkMgKPzm6v3f3fkd7ivb_RAITg-kWYamCM4qarBJmW8JGepY5O3dLC-jEX144myPb2fiiyfzaiLQuMLKSEcsyGT2OT1FQOjHU6w",
"expires_in": 300,
"refresh_expires_in": 0,
"token_type": "Bearer",
"not-before-policy": 0
}
You can now use the access_token to call Corvina APIs. Remember to honor the expires_in
value and refresh the token because it expires. With the access_token
you have the permissions that you declare in the scopes
parameter of the manifest.json
.